import {RouteLocationNormalized, RouteRecordName} from 'vue-router';
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useTagsViewStore = defineStore('tags-view', () => {
  const visitedViews = ref<RouteLocationNormalized[]>([]);
  const cachedViews = ref<RouteRecordName[]>([]);
  const iframeViews = ref<RouteLocationNormalized[]>([]);

  // 状态获取方法
  const getVisitedViews = (): RouteLocationNormalized[] => visitedViews.value as any;
  const getIframeViews = (): RouteLocationNormalized[] => iframeViews.value as any;
  const getCachedViews = (): RouteRecordName[] => cachedViews.value;

  // 核心操作方法
  const addView = (view: RouteLocationNormalized): void => {
    addVisitedView(view);
    addCachedView(view);
  };

  const addIframeView = (view: RouteLocationNormalized): void => {
    if (iframeViews.value.some(v => v.path === view.path)) return;
    iframeViews.value.push({
      ...view,
      title: view.meta?.title || 'no-name'
    });
  };

  const addVisitedView = (view: RouteLocationNormalized): void => {
    if (visitedViews.value.some(v => v.path === view.path)) return;
    const groupMatch = view.meta.group
      ? visitedViews.value.find(v => v.meta.group === view.meta.group)
      : undefined;
    if (groupMatch) {
      Object.assign(groupMatch, view);
    } else {
      visitedViews.value.push({
        ...view,
        title: view.meta?.title || 'no-name'
      });
    }
  };

  const addCachedView = (view: RouteLocationNormalized): void => {
    const name = view.name as string;
    if (!name || cachedViews.value.includes(name)) return;
    if (!view.meta?.noCache) cachedViews.value.push(name);
  };

  // 删除操作方法
  const delView = async (view: RouteLocationNormalized): Promise<any> => {
    try {
      await delVisitedView(view);
      await delCachedView(view);
      return {
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      };
    } catch (err) {
      throw err;
    }
  };

  const delVisitedView = async (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    visitedViews.value = visitedViews.value.filter(v => v.path !== view.path);
    iframeViews.value = iframeViews.value.filter(item => item.path !== view.path);
    return [...visitedViews.value] as any;
  };

  const delIframeView = async (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    iframeViews.value = iframeViews.value.filter(item => item.path !== view.path);
    return [...iframeViews.value] as any;
  };

  const delCachedView = async (view: RouteLocationNormalized): Promise<RouteRecordName[]> => {
    const name = view.name as string;
    const index = cachedViews.value.indexOf(name);
    index > -1 && cachedViews.value.splice(index, 1);
    return [...cachedViews.value];
  };

  const delOthersViews = async (view: RouteLocationNormalized): Promise<any> => {
    try {
      await delOthersVisitedViews(view);
      await delOthersCachedViews(view);
      return {
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      };
    } catch (err) {
      throw err;
    }
  };

  const delOthersVisitedViews = async (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    visitedViews.value = visitedViews.value.filter(v => v.meta?.affix || v.path === view.path);
    iframeViews.value = iframeViews.value.filter(item => item.path === view.path);
    return [...visitedViews.value] as any;
  };

  const delOthersCachedViews = async (view: RouteLocationNormalized): Promise<RouteRecordName[]> => {
    const name = view.name as string;
    const index = cachedViews.value.indexOf(name);
    cachedViews.value = index > -1 ? cachedViews.value.slice(index, index + 1) : [];
    return [...cachedViews.value];
  };

  const delAllViews = async (): Promise<any> => {
    try {
      await delAllVisitedViews();
      await delAllCachedViews();
      return {
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      };
    } catch (err) {
      throw err;
    }
  };

  const delAllVisitedViews = async (): Promise<RouteLocationNormalized[]> => {
    visitedViews.value = visitedViews.value.filter(v => v.meta?.affix);
    iframeViews.value = [];
    return [...visitedViews.value] as any;
  };

  const delAllCachedViews = async (): Promise<RouteRecordName[]> => {
    cachedViews.value = [];
    return [...cachedViews.value];
  };

  const updateVisitedView = (view: RouteLocationNormalized): void => {
    const target = visitedViews.value.find(v => v.path === view.path);
    if (target) Object.assign(target, view);
  };

  const delRightTags = async (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    const index = visitedViews.value.findIndex(v => v.path === view.path);
    if (index === -1) return [...visitedViews.value] as any;

    visitedViews.value = visitedViews.value.filter((item, idx) => {
      if (idx <= index || (item.meta?.affix)) return true;

      const cacheIndex = cachedViews.value.indexOf(item.name as string);
      cacheIndex > -1 && cachedViews.value.splice(cacheIndex, 1);

      if (item.meta?.link) {
        const iframeIndex = iframeViews.value.findIndex(v => v.path === item.path);
        iframeIndex > -1 && iframeViews.value.splice(iframeIndex, 1);
      }
      return false;
    });

    return [...visitedViews.value] as any;
  };

  const delLeftTags = async (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    const index = visitedViews.value.findIndex(v => v.path === view.path);
    if (index === -1) return [...visitedViews.value] as any;

    visitedViews.value = visitedViews.value.filter((item, idx) => {
      if (idx >= index || (item.meta?.affix)) return true;

      const cacheIndex = cachedViews.value.indexOf(item.name as string);
      cacheIndex > -1 && cachedViews.value.splice(cacheIndex, 1);

      if (item.meta?.link) {
        const iframeIndex = iframeViews.value.findIndex(v => v.path === item.path);
        iframeIndex > -1 && iframeViews.value.splice(iframeIndex, 1);
      }
      return false;
    });

    return [...visitedViews.value] as any;
  };

  return {
    visitedViews,
    cachedViews,
    iframeViews,

    getVisitedViews,
    getIframeViews,
    getCachedViews,

    addView,
    addIframeView,
    addVisitedView,
    addCachedView,
    delView,
    delVisitedView,
    delIframeView,
    delCachedView,
    delOthersViews,
    delOthersVisitedViews,
    delOthersCachedViews,
    delAllViews,
    delAllVisitedViews,
    delAllCachedViews,
    updateVisitedView,
    delRightTags,
    delLeftTags
  };
});
